home *** CD-ROM | disk | FTP | other *** search
- /*
- ShowInitIcon.c : Shows the icon during the init loading time
- */
-
- /*
- Note: This code is roughly based on an assembly language routine by
- Paul Mercer, Darin Adler, and Paul Snively from an idea by Steve Capps.
- We use this method to be compatible with other Mac INITs.
-
- It was converted to Think C by Eric Shapiro.
- 10/6/91 ebs Added HNoPurge call just to be extra safe.
- 4/26/91 ebs Added wrap-to-next-line support from James W. Walker
- 3/29/91 ebs Changed function name, added CIconHandle typecasts
- 12/12/89 ebs Called ClosePort() to release port memory
- */
-
- /* The low memory CurApName is a convenient place to store
- four bytes of information so the next INIT doesn't
- overwrite our ICON. We store into my_h the horizontal
- pixel location where the next INIT should go. We checksum
- the value and store the checksum in the next two bytes,
- so that INITs can determine whether they're the 1st one loaded.
- */
-
- #define CurApName 0x910
-
- extern short my_h : CurApName+32-4;
- extern short my_check : CurApName+32-2;
-
- #ifndef NULL
- #define NULL ( (void *)0 )
- #endif
-
- #define ICON_HEIGHT 32
- #define ICON_WIDTH 32
- #define FIRST_X 8 /* don't change this */
- #define BOTTOM_MARGIN 8
- #define DEF_MOVE_X_BY 40
- #define CHECKSUM_CONST 0x1021
- #define MIN_BIT_DEPTH 4 /* if 16 colors or more, use color icon */
-
-
- /*
- ShowInitIcon: Shows the icon specified in the correct place during startup
-
- NOTE:
- If Color QDraw is present and the main device has at least MIN_BIT_DEPTH
- set, we'll look for a color icon ('cicn' resource) first. If we can't
- find one, we'll look for the 'ICN#' resource.
-
- Passed:
- short icon_num; 'ICN#' or 'cicn' resource id
- short move_x_by; Pass -1 for default
-
- Returns:
- int 0=No error, <0=Error number
- */
- OSErr ShowInitIcon( short icon_num, short move_x_by)
- {
- short err;
- Handle icon_h=NULL; /* handle to 'ICN#' or 'cicn' resource */
- Boolean in_color=FALSE; /* TRUE='cicn' resource, else 'ICN#' */
- GrafPtr oldport;
- GrafPort newport; /* Entire GrafPort structure */
- Rect r; /* where to put the icon */
- SysEnvRec sys_rec;
- short screen_width;
-
- /* check for color quickdraw. If present, check bit depth of mainscreen.
- if >= MIN_BIT_DEPTH, then try to use color icon.
- */
- if ( err = SysEnvirons(1, &sys_rec) )
- return(err);
- if ( sys_rec.hasColorQD ) /* a Mac II or later... */
- {
- GDHandle gdev = GetGDevice(); /* get main screen */
- if ( (*(*gdev)->gdPMap)->pixelSize >= MIN_BIT_DEPTH )
- icon_h = (Handle)GetCIcon(icon_num);
- if ( icon_h != NULL )
- in_color = TRUE;
- }
-
- if ( icon_h == NULL ) /* no icon yet, try a B&W one */
- icon_h = Get1Resource('ICN#', icon_num);
- if ( icon_h == NULL )
- return(resNotFound); /* we're SOL here */
- HNoPurge( icon_h );
-
- GetPort(&oldport); /* save old GrafPort for later restoring */
-
- /* open a port so we can draw directly to screen. WindowMgrPort
- may not be initialized at this time.
- */
- OpenPort(&newport);
- SetPort(&newport);
-
- /* do a checksum on low memory to see if we're the 1st icon */
- /* if we are, then set x location. ^=XOR. */
- if ( ((my_h <<1) ^ CHECKSUM_CONST) != my_check )
- my_h = FIRST_X;
-
- #ifdef OLD_VERSION
- /* now plot the icon */
- r = newport.portRect;
- r.top = newport.portRect.bottom - (BOTTOM_MARGIN+ICON_HEIGHT);
- r.bottom = newport.portRect.bottom - BOTTOM_MARGIN;
- r.left = my_h;
- r.right = r.left + ICON_WIDTH;
- #endif
- /* now plot the icon 4/26/91 updated */
- screen_width = newport.portRect.right - newport.portRect.left;
- screen_width -= screen_width % DEF_MOVE_X_BY; /* in case screen isn't multiple of 40 */
- r.left = my_h % screen_width;
- r.right = r.left + ICON_WIDTH;
- r.top = newport.portRect.bottom - ((BOTTOM_MARGIN+ICON_HEIGHT) * (1 + my_h / screen_width));
- r.bottom = r.top + ICON_HEIGHT;
-
- if ( in_color )
- PlotCIcon(&r, (CIconHandle)icon_h); /* Toolbox's plot routine */
- else
- plot_icn(&r, icon_h); /* our routine */
-
- /* now offset the low memory location by move_x_by pixels */
- if ( move_x_by == -1 )
- move_x_by = DEF_MOVE_X_BY;
-
- my_h += move_x_by;
- my_check = (my_h<<1) ^ CHECKSUM_CONST;
-
- /* release the icon, restore the port */
- if ( in_color )
- DisposCIcon((CIconHandle)icon_h);
- else
- ReleaseResource(icon_h);
- SetPort(oldport);
- ClosePort(&newport); /* ebs 12/12/89 */
- return(0);
- }
-
-
- /*
- plot_icn : Plots an ICN# (ICON+mask) just the the Finder.
- */
- plot_icn(r, icn_handle)
- Rect *r;
- Handle icn_handle;
- {
- BitMap bm;
- char flags;
- GrafPtr cur_port;
-
- flags = HGetState(icn_handle);
- HLock(icn_handle);
- GetPort(&cur_port);
-
- /* we have to set up a BitMap structure to pass to CopyBits. We
- might be able to use CopyMask() call instead, but this should
- work on all Macs and CopyMask is only Mac+ or later. The 1st
- BitMap we use has baseAddr pointing 128 bytes into the ICN#,
- at the 1st bit of the mask. The 2nd BitMap points to the ICON.
- */
- bm.baseAddr = *icn_handle + ICON_WIDTH*ICON_HEIGHT/8; /* points to mask */
- bm.rowBytes = ICON_WIDTH / 8; /* ICON_WIDTH/8 must be power of 2 */
- SetRect(&bm.bounds, 0, 0, ICON_WIDTH, ICON_HEIGHT);
-
- /* punch a hole in the Desktop using bit-clear mode and the mask */
- CopyBits(&bm, &cur_port->portBits, &bm.bounds, r, srcBic, NULL);
-
- /* now copy the icon into the punched hole */
- bm.baseAddr = *icn_handle; /* points to ICON */
- CopyBits(&bm, &cur_port->portBits, &bm.bounds, r, srcOr, NULL);
-
- HSetState(icn_handle, flags);
- }
-